package com.weishaoying.practice.shiro;

import com.weishaoying.practice.entity.SysPermission;
import com.weishaoying.practice.entity.SysUser;
import com.weishaoying.practice.service.SysService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

//http://shiro.apache.org/spring.html

public class BccRealm extends AuthorizingRealm {

    private String PREFIX = "--------BccRealm----";

    @Autowired
    private SysService sysService;

    // 设置realm的名称
    @Override
    public void setName(String name) {
        super.setName("BccRealm");
    }

    //认证方法,相当于passport
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        // token是用户输入的用户名和密码
        System.out.println(PREFIX + "-token = " + token);
        // 1.从token中取出用户名
        String username = (String) token.getPrincipal();
        System.out.println(PREFIX + "username = " + username);

        //通过用户名查询用户信息，shiro会自动调用凭证匹配密码是否正确
        SysUser sysUser = sysService.findSysUserByUserCode(username);
        if (sysUser == null) {
            //会触发UnknownAccountException
            return null;
        }
        //数据库中存储的密码和盐
        String password = sysUser.getPassword();
        String salt = sysUser.getSalt();
        System.out.println("----password = " + password);
        System.out.println("----salt = " + salt);

        //是否有必要
        //List<SysPermission> menus = sysService.findMenuListByUserId(sysUser.getId());
        //userDto.setMenus(menus);
        return new SimpleAuthenticationInfo(sysUser, password, ByteSource.Util.bytes(salt), this.getName());
        //第一个参数放什么，下面就取到什么，也可以放username
        //return new SimpleAuthenticationInfo(sysUser, password, this.getName());

        //**************************** http://blog.csdn.net/eson_15/article/details/51787391
    }


    // 授权相当于UC
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //从 principals获取主身份信息
        //将getPrimaryPrincipal方法返回值转为真实身份类型（在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型），
        SysUser sysUser = (SysUser) principals.getPrimaryPrincipal();

        //根据身份信息获取权限信息
        List<SysPermission> permissionList = sysService.findPermissionListByUserId(sysUser.getId());

        List<String> permissions = new ArrayList<>();
        if (permissionList != null) {
            for (SysPermission sysPermission : permissionList) {
                //将数据库中的权限标签放入集合
                permissions.add(sysPermission.getPercode());
            }
        }
        permissions.add("user:query");
        permissions.add("book:edit");
        permissions.add("book:query");
        permissions.add("book:delete");
        permissions.add("car:edit");
        permissions.add("car:query");

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addStringPermissions(permissions);
        System.out.println("permissions = " + permissions);
        //TODO:查询用户拥有的角色
        Set<String> roles = new HashSet<>();
        roles.add("teacher");
        roles.add("student");
        authorizationInfo.setRoles(roles);
//        Set<Permission> objectPermissions = new HashSet<>();
//        objectPermissions.add("");
//        objectPermissions.add("");
//        simpleAuthorizationInfo.setObjectPermissions(objectPermissions);
        return authorizationInfo;

        //****************************网络资料
//        String username = (String) principals.getPrimaryPrincipal(); //获取用户名
//        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//        authorizationInfo.setRoles(userService.getRoles(username));
//        authorizationInfo.setStringPermissions(userService.getPermissions(username));
//        return authorizationInfo;
    }

    //清除缓存
    public void clearCached() {
        System.out.println(PREFIX + "clearCached");
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
        super.clearCache(principals);
    }

    //http://blog.csdn.net/catoop/article/details/50520958
    //http://sishuok.com/forum/blogPost/list/0/7460.html
    //https://github.com/527515025/springBoot
    //http://blog.csdn.net/u012373815/article/details/57532292
    //https://github.com/527515025/springBoot

}